<template>
  <div>
    <a-page-header
      title="用户管理"
      :ghost="false"
      sub-title="表单页用于向用户收集或验证信息，基础表单常见于数据项较少的表单场景"
    />

    <a-card class="mt-1" size="small">
      <a-form
        label-align="left"
        :labelCol="{ span: 8 }"
        :wrapperCol="{ span: 16 }"
        layout="inline"
      >
        <a-row align="middle">
          <a-col :span="4">
            <a-form-item label="用户名">
              <a-input
                placeholder="用户名"
                v-model:value="searchForm.username"
              />
            </a-form-item>
          </a-col>
          <a-col :span="4">
            <a-form-item label="姓名">
              <a-input placeholder="姓名" v-model:value="searchForm.name" />
            </a-form-item>
          </a-col>
          <a-col :span="4">
            <a-form-item label="部门">
              <a-input
                placeholder="部门"
                v-model:value="searchForm.department"
              />
            </a-form-item>
          </a-col>
          <a-col :span="1">
            <a-button type="primary" @click="search">查询</a-button>
          </a-col>
          <a-col :span="1">
            <a-button html-type="reset" @click="reset" style="margin-left: 8px">
              重置
            </a-button>
          </a-col>
        </a-row>
      </a-form>
    </a-card>

    <a-card class="mt-1" size="small">
      <div style="margin-bottom: 8px">
        <a-button size="small" type="primary" @click="showModal(undefined)">
          添加
        </a-button>
      </div>

      <a-table
        bordered
        size="middle"
        :data-source="data"
        :columns="columns"
        rowKey="id"
        :loading="loading"
        :pagination="pagination"
        @change="handleChange"
      >
        <template #roles="{ record }">
          <a-tag
            v-for="(role, index) in record.roles"
            :key="index"
            color="blue"
          >
            {{ role.name }}
          </a-tag>
        </template>

        <template #status="{ record }">
          <a-tag v-if="record.status == 10" color="blue">启用</a-tag>
          <a-tag v-else-if="record.status == 9" color="red">停用</a-tag>
          <a-tag v-else color="default">已删除</a-tag>
        </template>

        <template #createdAt="{ record }">
          {{ datefmt(record.created_at, 'YYYY-MM-DD HH:mm:ss') }}
        </template>

        <template #operation="{ record }">
          <template v-if="record.status == 9 || record.status == 10">
            <a @click="showModal(record)">修改</a>
            <a-divider type="vertical" />
          </template>
          <a @click="showLog(record.id)">日志</a>

          <template v-if="record.status == 9 || record.status == 10">
            <a-divider type="vertical" />
            <a v-if="record.status == 9" @click="confirm(record, 10)">启用</a>
            <a v-else-if="record.status == 10" @click="confirm(record, 9)"
              >暂停</a
            >
          </template>
        </template>
      </a-table>
    </a-card>

    <teleport to="body">
      <a-modal
        :title="form.id == '' ? '添加' : '修改'"
        v-model:visible="visible"
        :confirm-loading="submitting"
        @ok="submit"
      >
        <a-form :label-col="{ span: 4 }" :wrapper-col="{ span: 14 }">
          <a-form-item label="用户名" v-bind="errors.username">
            <a-input placeholder="用户名" v-model:value="form.username" />
          </a-form-item>
          <a-form-item label="姓名" v-bind="errors.name">
            <a-input placeholder="姓名" v-model:value="form.name" />
          </a-form-item>
          <a-form-item label="邮箱" v-bind="errors.email">
            <a-input placeholder="邮箱" v-model:value="form.email" />
          </a-form-item>
          <a-form-item label="角色" v-bind="errors.roles">
            <a-select
              mode="multiple"
              v-model:value="form.roles"
              style="width: 100%"
              placeholder="角色"
              :filter-option="false"
              :max-tag-count="2"
              :not-found-content="fetching ? undefined : null"
              @focus="fetchRole"
            >
              <template v-if="fetching" #notFoundContent>
                <a-spin size="small" />
              </template>
              <a-select-option v-for="v in roles" :key="v.code">
                {{ v.name }}
              </a-select-option>
            </a-select>
          </a-form-item>
          <a-form-item label="状态" v-bind="errors.status">
            <a-radio-group v-model:value="form.status">
              <a-radio :value="10">启用</a-radio>
              <a-radio :value="9">停用</a-radio>
            </a-radio-group>
          </a-form-item>
        </a-form>
      </a-modal>
    </teleport>

    <teleport to="body">
      <a-drawer
        width="30%"
        placement="right"
        :closable="true"
        :visible="logVisible"
        @close="closeLog"
      >
        <template v-if="logs.length > 0">
          <a-timeline>
            <a-timeline-item
              v-for="(log, index) in logs"
              :key="index"
              color="green"
            >
              {{ log.created_at }} {{ log.message }} IP: {{ log.ip }}
              <template v-if="log.isException" #dot>
                <icon name="ExclamationCircleOutlined" style="color: #fa8c16" />
              </template>
            </a-timeline-item>
          </a-timeline>
        </template>
      </a-drawer>
    </teleport>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive, Ref, ref, createVNode, inject } from 'vue';
import { Icon } from '@/components';

import {
  Empty,
  Card,
  Col,
  Row,
  PageHeader,
  Table,
  Button,
  Input,
  Form,
  Divider,
  Modal,
  Tag,
  Drawer,
  Timeline,
  Radio,
  Select,
  Spin,
} from 'ant-design-vue';
import { getUserlogs } from '@/api/log';
import { Log, Role, User } from '@/types';
import { datefmt } from '@/util';
import { debounce } from 'lodash-es';
import { getRoles } from '@/api/role';
import { useUser, usePostUser } from './hooks/useUser';

const getUserlog = async (id: number) => {
  const res = await getUserlogs(id);
  if (res != undefined && res.status == 200) {
    return res.data;
  }
  return [];
};

export default defineComponent({
  components: {
    AEmpty: Empty,
    ACard: Card,
    ACol: Col,
    ARow: Row,
    APageHeader: PageHeader,
    ATable: Table,
    AButton: Button,
    AInput: Input,
    AForm: Form,
    AFormItem: Form.Item,
    ADivider: Divider,
    AModal: Modal,
    ATag: Tag,
    ADrawer: Drawer,
    ATimeline: Timeline,
    ATimelineItem: Timeline.Item,
    Icon: Icon,
    ASpin: Spin,
    ARadio: Radio,
    ARadioGroup: Radio.Group,
    ASelect: Select,
    ASelectOption: Select.Option,
  },
  setup() {
    const { columns, search: request, data, pagination, loading } = useUser();

    const handleChange = (page: any, filters: any, sorter: any) => {
      request({
        page: page.current,
        pageSize: page.pageSize,
        sortField: sorter.field,
        sortOrder: sorter.order,
      });
    };

    const searchForm = reactive({
      name: '',
      username: '',
      department: '',
    });
    const search = () => {
      request({
        page: pagination.value.current,
        pageSize: pagination.value.pageSize,
        ...searchForm,
      });
    };
    const reset = () => {
      request({
        page: pagination.value.current,
        pageSize: pagination.value.pageSize,
      });
    };
    // -----------------------------------

    const reload = <() => {}>inject('reload');

    const { errors, post, submitting, form, resetForm } = usePostUser();
    const visible = ref(false);
    const submit = async () => {
      await post();
      visible.value = false;
      reload();
    };

    const showModal = (user?: User) => {
      if (user != undefined) {
        Object.assign(form, user);
      } else {
        resetForm();
      }
      visible.value = true;
    };

    const confirm = (user: User, value: number) => {
      Modal.confirm({
        icon: createVNode(Icon, { name: 'ExclamationCircleOutlined' }),
        content: `确定要${value == 9 ? '停用' : '启用'}当前角色?`,
        async onOk() {
          resetForm();
          form.status = value;
          form.id = `${user.id}`;
          form.name = user.name;
          form.username = user.username;

          await post();
        },
      });
    };

    const roles = ref(<Role[]>[]);
    const fetching = ref(false);
    const fetchRole = debounce(() => {
      if (roles.value.length > 0) {
        return;
      }

      fetching.value = true;
      getRoles({ page: 1, pageSize: 900 }).then((res: any) => {
        roles.value = res.data.items;
        fetching.value = false;
      });
    });

    const logs: Ref<Log[]> = ref([]);
    const logVisible = ref(false);
    const closeLog = () => {
      logVisible.value = false;
    };
    const showLog = async (id: number) => {
      logVisible.value = true;
      logs.value = await getUserlog(id);
    };

    return {
      showModal,
      submitting,
      submit,
      errors,
      form,

      fetchRole,
      fetching,
      roles,
      visible,

      data,
      search,
      searchForm,
      reset,
      pagination,
      handleChange,
      loading,
      columns,

      logVisible,
      closeLog,
      showLog,
      logs,

      datefmt,
      confirm,
    };
  },
});
</script>

<style lang="less" scoped>
</style>
